<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>QUnit Tests</title>
    <link rel="stylesheet" href="../node_modules/qunitjs/qunit/qunit.css">
</head>
<body>

<div id="qunit"></div>
<div id="qunit-fixture"></div>
<form id="dummy-form" style="visibility: hidden"></form>

<script src="../node_modules/jquery/dist/jquery.min.js"></script>
<script src="../node_modules/qunitjs/qunit/qunit.js"></script>
<script src="../form-validator/jquery.form-validator.js"></script>
<script src="../node_modules/numeral/numeral.js"></script>
<script>
(function($) {

    var $form = $('#dummy-form'), $in=null;
    window.$form = $form;
    window.$in = $in;

    function input(val, dataValidationAttr, elAttr, elemName) {
        if(!elAttr)
            elAttr = {};
        if( typeof dataValidationAttr === 'string') {
            elAttr['data-validation'] = dataValidationAttr;
        } else if(dataValidationAttr) {
            $.each(dataValidationAttr, function(x, val) {
                if( x === '' ) {
                    elAttr['data-validation'] = val;
                } else {
                    elAttr['data-validation-'+x] = val;
                }
            });
        }

        elAttr['value'] = val;
        $in = $('<'+(elemName || 'input')+' />', elAttr);
        $in.appendTo($form);
        return $in;
    }

    function clearForm() {
        $form.children().remove();
    }

    function runTest(obj, validation) {
        var $el = typeof obj.val == 'string' ? input(obj.val, validation) : obj.val;
        var result = $.formUtils.validateInput($el, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);

        var message;
        if (typeof obj.val === 'string' ) {
            message  = 'Check that "'+obj.val+'" is '+(obj.isValid ? 'valid':'invalid');
        }
        else {
            message = 'Check that '+$el.get(0).nodeName+'[value="'+obj.val.attr('value')+'"] is '+(obj.isValid ? 'valid':'invalid');
        }

        if (!result.shouldChangeDisplay && obj.isValid ) {
            equal(null, null, message);
        }
        else {
            equal(result.isValid, obj.isValid, message);
        }
    }

    function runAllTests() {

        /*
         * Image dimension checks
         */
        var imgDimensionChecks = {
                'square100x100.png' : {
                    'min100x100' : false,
                    'min100x10' : false,
                    'min100' : false,
                    'min200x500' : true,
                    'min200x10': true,
                    'min200' : true,
                    'min100x200' : true,

                    'max100x100' : false,
                    'max100x10' : true,
                    'max100' : false,
                    'max200x500' : false,
                    'max200x10': true,
                    'max200' : false,
                    'max90x200' : true,

                    '100x100-500x500' : false,
                    '100x200-500x500' : true,
                    '200x100-500x500' : true,
                    '50x50-90x500' : true,
                    '30-200x200' : false,
                    '30-100' : false,
                    '30-50' : true
                },
                'rectangle100x50.png' : {
                    'min100x100' : true,
                    'min100x10' : false,
                    'min100' : true,
                    'min200x500' : true,
                    'min200x10': true,
                    'min200' : true,
                    'min10x50' : false
                }
            },
            imageRatioChecks = {
                'square100x100.png' : {
                    '1:1' : false,
                    '1:2-1:1' : false,
                    '8:10-12:10' : false,
                    '1:2' : true,
                    '2:1': true
                },
                'rectangle100x50.png' : {
                    '1:1' : true,
                    '1:2-1:1' : true,
                    '8:10-12:10' : true,
                    '1:2' : true,
                    '2:1': false
                }
            };


        $.each(imgDimensionChecks, function(imgFileName, assertions) {
            var img = document.createElement('IMG');
            img.onload = function() {
                test('Check image dim on '+imgFileName, function() {
                    $.each(assertions, function(valRule, shouldFail) {
                        var didFail = $.formUtils.checkImageDimension(img, valRule, {}) ? true:false;
                        equal(didFail, shouldFail, valRule+' should '+(shouldFail ? 'fail':'NOT fail')+' validation');
                    });
                    $.each(imageRatioChecks[imgFileName], function(ratioDeclaration, shouldFail) {
                       var didFail =  $.formUtils.checkImageRatio(img, ratioDeclaration, {imageRatioNotAccepted:'errorr...'}) ? true:false;
                        equal(didFail, shouldFail, ratioDeclaration+' should '+(shouldFail ? 'fail':'NOT fail')+' validation');
                    });
                });
            };
            img.src = document.location.href.substr(0, document.location.href.lastIndexOf('/')) +'/test-data/'+imgFileName;
        });

        /*
        * Test utility method for getting input values
        */
        test('$.formUtils.getValue', function(assert) {


          var input = '<input value="text">';
          assert.equal($.formUtils.getValue($(input)), 'text');

          var select = '<select><option>A</option><option selected>B</option><option>C</option></select>';
          assert.equal($.formUtils.getValue($(select)), 'B');

          var selectMultipleWithoutSelected = '<select multiple><option>A</option><option>B</option><option>C</option></select>';
          assert.equal($.isEmptyObject($.formUtils.getValue($(selectMultipleWithoutSelected))), true);

          var selectMultiple = '<select multiple><option>A</option><option selected>B</option><option selected>C</option></select>';
          var selected = $.formUtils.getValue($(selectMultiple));
          assert.equal(selected.length, 2);
          assert.equal(selected[0], 'B');
          assert.equal(selected[1], 'C');


        });

      /*
      * Test $.fn.validate
      */
      test('Test $.fn.validate() ', function(assert) {
        clearForm();
        assert.expect(1);
        var $input = input('--', {'':'required alphanumeric'});
        $input.attr('id', 'some-input');
        $('#some-input').validate(function(valid, elem) {
          assert.equal(false, valid);
        });
      });

      /*
       * Test validation of hidden inputs
       */
      test('Validation of hidden inputs', function(assert) {
        clearForm();
        assert.expect(3);
        var $input = input('--', {'':'required alphanumeric'});
        assert.equal(false, $input.closest('form').isValid({}, {}, false));
        $input.hide();
        assert.equal(true, $input.closest('form').isValid({}, {}, false));
        $input.validate(function(valid) {
          assert.equal(false, valid);
        }, {validateHiddenInputs: true});
      });

        /*
         * Test error message
         */
        test('Error messages', function() {

            // default inline (below input) error messages
            var $input = input('', 'required'),
                result = $.formUtils.validateInput($input, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(result.errorMsg, 'This is a required field', 'Incorrect message');

            // messages on top of form
            var configWithTopMsg = $.formUtils.defaultConfig();
            configWithTopMsg.errorMessagePosition = "top";
            result = $.formUtils.validateInput($input, $.formUtils.LANG, configWithTopMsg, $form);
            equal(result.errorMsg, 'You have not answered all required fields', 'Incorrect message');

            $input = input('--', {'':'required alphanumeric', 'error-msg-alphanumeric':'custom for alphanum'}),
            result = $.formUtils.validateInput($input, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(result.errorMsg, 'custom for alphanum', 'Incorrect message');

            $input = input('sam', {'':'required alphanumeric length', length:'min10', 'error-msg-alphanumeric':'custom for alphanum'}),
            result = $.formUtils.validateInput($input, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(result.errorMsg, 'The input value is shorter than 10 characters', 'Incorrect message');

        });

        /*
         * E-MAIL VALIDATION
         */
        test("E-mail validation", function() {

            clearForm();

            var values = [
                {val: 'sasas@sdssds.se', isValid : true},
                {val: 'sasás@sdssds.se', isValid : false},
                {val: 'sas+as@sdssds.se', isValid : true},
                {val: '', isValid : false},
                {val: 'asdsd@sdsds.se', isValid : true},
                {val: 'valid-domain@website.COM', isValid : true},
                {val: 'asdsdsd@sdsd.co.uk', isValid : true},
                {val: 'sasas@sdsd.xxx', isValid : true},
                {val: 'sasas@9gag.com', isValid : true},
                {val: 'sasas@.9gag.com', isValid : false},
                {val: 'sasas@sdsd.xxz', isValid : true},
                {val: '@sdsd.xxz', isValid : false},
                {val: 'sasas@', isValid : false},
                {val: 'sasas.se', isValid : false},
                {val: 'sasas-sdsd.com', isValid : false},
                {val: '"sasas-sdsd"@monkey.com', isValid : true},
                {val: '"sasas-sdsd"sdfsdf.sdff@monkey.com', isValid : true},
                {val: 'sdf"sasas-sdsd"@monkey.com', isValid : false}
            ];

            $.each(values, function(i, obj) {
                runTest(obj, 'email');
            });
        });

        /*
         * URL VALIDATION
         */
        test("URL validation", function() {

            clearForm();

            var links = [
                {val: 'klsdmfklsmdf', isValid: false},
                {val: 'http://google.se', isValid: true},
                {val: 'https://google.se/test/?arge=hej_&arg[]=123', isValid: true},
                {val: 'http://google.test.de', isValid: true},
                {val: 'http://test.xn--fiqz9s', isValid: true},
                {val: 'http://test.youtube', isValid: true},
                {val: 'http://google.test.co.uk/', isValid: true}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'url');
            });
        });


        /*
         * DOMAIN VALIDATION
         */
        test("Domain validation", function() {

            clearForm();

            var links = [
                {val:'domain.xxx', isValid:true},
                {val:'domain.com', isValid:true},
                {val:'www.domain.com', isValid:true},
                {val:'test.xn--fiqz9s', isValid:true},
                {val:'test..xn--fiqz9s', isValid:false},
                {val:'q.com', isValid:true},
                {val:'amazone.website.tippit.de', isValid:true},
                {val:'amazone.website.co.uk', isValid:true},
                {val:'http://domain.se', isValid:false},
                {val:'http://www.domain.se', isValid:false},
                {val:'http://www.domain.se/', isValid:false},
                {val:'domain.com/', isValid:false},
                {val:'', isValid:false},
                {val:'asdfasdf', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'domain');
            });
        });

        /*
         * REQUIRED VALIDATION
         */
        test("Require validation", function() {

            clearForm();

            var links = [
                {val:'a', isValid:true},
                {val:'asdf askldfmlksamdf', isValid:true},
                {val:'  ', isValid:false},
                {val:"\n", isValid:false},
                {val:'', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'required');
            });
        });

        /*
         * ALPHANUMERIC VALIDATION
         */
        test("Alphanumeric validation", function() {

            clearForm();

            var links = [
                {val:'a', isValid:true},
                {val:'asdXAvs1', isValid:true},
                {val:'a  b', isValid:false},
                {val:'a-_ bäöåA', isValid:false},
                {val:'abbb', isValid:true},
                {val:'a,bbb', isValid:false},
                {val:input('a,bbb', {'allowing':',', '':'alphanumeric'}), isValid:true},
                {val:input('a b', {'allowing':' ', '':'alphanumeric'}), isValid:true},
                {val:input('', {'allowing':' ', length:'3-12', '':'length alphanumeric'}), isValid:false},
                {val:input('a-_ bäöåÖA', {'allowing':' -_öäåÄÖÅ', '':'alphanumeric'}), isValid:true},
                {val:'bäöåA', isValid:false},
                {val:'ë', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'alphanumeric');
            });
        });

        /*
         * LETTER-NUMERIC VALIDATION
         */
        test("Letter-numeric validation", function() {

            clearForm();

            var links = [
                {val:'a', isValid:true},
                {val:'asdXAvs1', isValid:true},
                {val:'a  b', isValid:false},
                {val:'a-_ bäöåA', isValid:false},
                {val:'abbb', isValid:true},
                {val:'a,bbb', isValid:false},
                {val:input('abbbé', {'allowing':',', '':'letternumeric'}), isValid:true},
                {val:input('a b', {'allowing':' ', '':'alphanumeric'}), isValid:true},
                {val:input('', {'allowing':' ', length:'3-12', '':'length letternumeric'}), isValid:false},
                {val:'bäöåA', isValid:true},
                {val:'bäöåA®', isValid:false},
                {val:'ë', isValid:true}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'letternumeric');
            });
        });

        /*
         * CREDIT CARD VALIDATION
         */
        test("Credit card validation", function() {

            clearForm();

            var links = [
                {val:'4000000000000002', isValid:true},
                {val:input('4000000000000002', {'allowing':'visa', '':'creditcard'}), isValid:true},
                {val:input('4000000000000002', {'allowing':'mastercard, discover, visa', '':'creditcard'}), isValid:true},
                {val:input('501800000009', {'allowing':'maestro', '':'creditcard'}), isValid:true},
                {val:input('501800000009', {'allowing':'visa', '':'creditcard'}), isValid:false},
                {val:input('501800000009', {'allowing':'jadajada,maestro,mastercard', '':'creditcard'}), isValid:true},
                {val:input('5100000000000008', {'allowing':'mastercard', '':'creditcard'}), isValid:true},
                {val:input('6011000000000004', {'allowing':'discover', '':'creditcard'}), isValid:true},
                {val:input('6011000000000005', {'allowing':'discover', '':'creditcard'}), isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'creditcard');
            });
        });

        test('isValid()', function() {

            $form.empty();
            $form.append(input('4000000000000002', {'allowing':'visa', '':'creditcard'}));
            $form.append(input('', {'optional':'true', '':'alphanumeric'}));
            $form.append(input('', 'alphanumeric'));
            $form.append(input('4000000000000002', 'alphanumeric'));

            equal(
                $form.isValid(false, false, false),
                false
            );

            $form.empty();
            $form.append(input('4000000000000002', {'allowing':'visa', '':'creditcard'}));
            $form.append(input('', {'optional':'true', '':'alphanumeric'}));
            $form.append(input('fff', 'alphanumeric'));
            $form.append(input('4000000000000002', 'alphanumeric'));

            equal(
                $form.isValid(false, false, false),
                true
            );

        });

        /*
         * CVV VALIDATION
         */
        test("CVV validation", function() {

            clearForm();

            var links = [
                {val:'012', isValid:true},
                {val:'0124', isValid:false},
                {val:'000', isValid:true},
                {val:'01', isValid:false},
                {val:'a12', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'cvv');
            });

            // check with amex only
            var $cCard = input('', {'allowing':'amex', '':'creditcard'}),
                $cvv = input('1234', 'cvv'),
                result;

            // let the validator know which type of card we're validating
            $.formUtils.validateInput($cCard, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);

            result = $.formUtils.validateInput($cvv, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(
                true,
                result.isValid
            );

            $cvv.val('123');
            result = $.formUtils.validateInput($cvv, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(
                false,
                result.isValid
            );

        });


        /*
         * DISABLED VALIDATION
         */
        test("Do not validate disabled", function() {
            clearForm();
            var $input = input('a--b', {'allowing':'', '':'alphanumeric'});
            $input.attr('disabled', 'disabled');
            runTest({val:$input, isValid: true});
        });

        /*
         * NUMBER VALIDATION type=text (HTML4)
         */
        test('Number validation for <input type=text"/>', function() {

            clearForm();

            var links = [
                {val: '123',    isValid: true},
                {val: '',       isValid: false},
                {val: 'asdfsd', isValid: false},
                {val: '-123',   isValid: false},
                {val: '1.032',  isValid: false},
                {val: '-1.032', isValid: false},
                {val: input('-123'  , {'allowing': 'negative', '': 'number'}),                isValid: true},
                {val: input('-1',     {'allowing': 'range[-10;10],negative', '': 'number'}), isValid: true},
              //Test ranges
                {val: input('12',     {'allowing': 'range[1;10]', '':'number'}), isValid: false},
                {val: input('-1',     {'allowing': 'range[1;10]', '':'number'}), isValid: false},
                {val: input('1',      {'allowing': 'range[1;10]', '':'number'}), isValid: true},
                {val: input('10',     {'allowing': 'range[1;10]', '':'number'}), isValid: true},
                {val: input('5',      {'allowing': 'range[1;10]', '':'number'}), isValid: true},
                {val: input('',       {'optional': true, '': 'number' }),        isValid: true},
              //Test floats
                {val: input('1.023' , {'allowing': 'float', '': 'number'}),      isValid: true},
                {val: input('-1.023', {'allowing': 'float,negative', '': 'number'}),        isValid: true},
                {val: input('1.0234', {'allowing': 'float,negative', '': 'number'}),        isValid: true},
                {val: input('1.0235', {'allowing': 'float,negative,number', '': 'number'}), isValid: true},
                {val: input('1.0236', {'allowing': 'float,negative,number', 'decimal-separator': ',',
                            '': 'number'}),                                                  isValid: false},
                {val: input('1,023',  {'allowing': 'float,negative,number', 'decimal-separator':',',
                            '': 'number'}),                                                  isValid: true},
                {val: input('0.0001', {'allowing': 'range[0.05;0.9]', '': 'number'}),        isValid: false},
                {val: input('0.06',   {'allowing': 'range[0.05;0.9],float', '': 'number'}),  isValid: true}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'number');
            });
        });

        /**
         *  NUMBER VALIDATION for type = "number" (HTML5)
         */
        test('Number validation for <input type="number"/>', function () {
          clearForm();
          var links = [];
          var numberType = {type: 'number'};
          links.push(
            {val: input('123',    {'': 'number'}, numberType), isValid: true},
            {val: input('',       {'': 'number'}, numberType), isValid: false},
            {val: input('asdfsd', {'': 'number'}, numberType), isValid: false},
            {val: input('-123',   {'': 'number'}, numberType), isValid: false},
            {val: input('1.032',  {'': 'number'}, numberType), isValid: false},
            {val: input('-1.032', {'': 'number'}, numberType), isValid: false},
            {val: input('-123'  , {'allowing': 'negative', '': 'number'}, numberType),   isValid: true},
            {val: input('',       {'optional': true, '': 'number' }, numberType),  isValid: true},
            //Test ranges
            {val: input('12',     {'allowing': 'range[1;10]', '':'number'}, numberType), isValid: false},
            {val: input('-1',     {'allowing': 'range[1;10]', '':'number'}, numberType), isValid: false},
            {val: input('1',      {'allowing': 'range[1;10]', '':'number'}, numberType), isValid: true},
            {val: input('10',     {'allowing': 'range[1;10]', '':'number'}, numberType), isValid: true},
            {val: input('5',      {'allowing': 'range[1;10]', '':'number'}, numberType), isValid: true},
            {val: input('-1',     {'allowing': 'range[-10;10],negative', '': 'number'}, numberType), isValid: true},
            //Test floats
            {val: input('1.023' , {'allowing': 'float', '': 'number'}, numberType),      isValid: true},
            {val: input('-1.023', {'allowing': 'float,negative', '': 'number'}, numberType),        isValid: true},
            {val: input('1.0234', {'allowing': 'float,negative', '': 'number'}, numberType),        isValid: true},
            {val: input('1.0235', {'allowing': 'float,negative,number', '': 'number'}, numberType), isValid: true},
            {val: input('1.0236', {'allowing': 'float,negative,number', 'decimal-separator': ',',
                        '': 'number'}, numberType),                                                 isValid: false},
            {val: input('0.0001', {'allowing': 'range[0.05;0.9]', '': 'number'}, numberType),       isValid: false},
            {val: input('0.06',   {'allowing': 'range[0.05;0.9],float', 'decimal-separator': '.',
                                   '': 'number'}, numberType), isValid: true}
          );
          /* Tests that fail with HTML input type number because of bugs in how browsers handle decimal separators:
           {val: input('1,023',  {'allowing': 'float,negative,number', 'decimal-separator':',',
                 '': 'number'}, {'lang': 'no', type: 'number'}),                                    isValid: true},
           */

          $.each(links, function(i, obj) {
            runTest(obj, 'number');
          });
        });
        /*
         * DATE VALIDATION
         */
        test("Date validation", function() {

            clearForm();

            var dates = [
                {val:'2000-01-01', isValid:true},
                {val:'2000-01-1', isValid:false},
                {val:'2000-01-32', isValid:false},
                {val:'2000-02-29', isValid:true}, // leap year
                {val:'2013-02-29', isValid:false},
                {val:'2000-04-31', isValid:false},
                {val:'2000-13-1', isValid:false},
                {val:input('2000-1-1', {'':'date'}), isValid:false},
                {val:input('2000-1-1', {'':'date', 'require-leading-zero':'false'}), isValid:true},
                {val:'-01-01', isValid:false},
                {val:input('01/01/2000', {'format':'dd/mm/yyyy', '':'date'}), isValid:true},
                {val:input('29/02/2000', {'format':'dd/mm/yyyy', '':'date'}), isValid:true},
                {val:input('02/2000', {'format':'mm/yyyy', '':'date'}), isValid:true},
                {val:input('29/02/2013', {'format':'dd/mm/yyyy', '':'date'}), isValid:false},
                {val:input('29/13/2013', {'format':'dd/mm/yyyy', '':'date'}), isValid:false},
                {val:input('29/00/2013', {'format':'dd/mm/yyyy', '':'date'}), isValid:false},
                {val:'', isValid:false},
                {val:input('', {'optional':'true', 'format':'dd/mm/yyyy', '':'date'}), isValid:true},
                {val:'2014-01-01', isValid:true},
                {val:'1880-01-01', isValid:true}
            ];

            $.each(dates, function(i, obj) {
                runTest(obj, 'date');
            });
        });

        /*
         * BIRTH DATE VALIDATION
         */
        test("Birth date validation", function() {

            clearForm();

            var dates = [
                {val:'2000-01-01', isValid:true},
                {val:'2000-01-1', isValid:false},
                {val:'2000-01-32', isValid:false},
                {val:'2000-02-29', isValid:true}, // leap year
                {val:'2013-02-29', isValid:false},
                {val:'2000-04-31', isValid:false},
                {val:'2000-13-1', isValid:false},
                {val:'2000-1-1', isValid:false},
                {val:'-01-01', isValid:false},
                {val:input('01/01/2000', {'format':'dd/mm/yyyy', '':'birthdate'}), isValid:true},
                {val:input('29/02/2000', {'format':'dd/mm/yyyy', '':'birthdate'}), isValid:true},
                {val:input('29/02/2013', {'format':'dd/mm/yyyy', '':'birthdate'}), isValid:false},
                {val:input('29/13/2013', {'format':'dd/mm/yyyy', '':'birthdate'}), isValid:false},
                {val:input('29/00/2013', {'format':'dd/mm/yyyy', '':'birthdate'}), isValid:false},
                {val:'2030-01-01', isValid:false}, // no future date
                {val:'1880-01-01', isValid:false}, // no date that is to old
                {val:input('2000-01-01', {'age-range':'0-5', '':'birthdate'}), isValid:false},
                {val:input('2000-01-01', {'age-range':'17-100', '':'birthdate'}), isValid:true}            ];

            $.each(dates, function(i, obj) {
                runTest(obj, 'birthdate');
            });
        });

        /*
         * TIME VALIDATION
         */
        test("Time validation", function() {

            clearForm();

            var links = [
                {val:'00:00', isValid:true},
                {val:'00:01', isValid:true},
                {val:'09:59', isValid:true},
                {val:'19:59', isValid:true},
                {val:'19:60', isValid:false},
                {val:'19:61', isValid:false},
                {val:'24:01', isValid:false},
                {val:'24:00', isValid:false},
                {val:'2200', isValid:false},
                {val:'', isValid:false},
                {val:'23', isValid:false},
                {val:'23;00', isValid:false},
                {val:'23-00', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'time');
            });
        });


        /*
         * SWEDISH MOBILE VALIDATION
         */
        test("Swe mobile validation", function() {

            clearForm();

            var links = [
                {val:'0702777118', isValid:true},
                {val:'0722777118', isValid:true},
                {val:'46702777118', isValid:true},
                {val:'45702777118', isValid:false},
                {val:'+46702777118', isValid:true},
                {val:'+45702777118', isValid:false},
                {val:'0732777118', isValid:true},
                {val:'0302777118', isValid:false},
                {val:'07027771', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'swemobile');
            });
        });

        /*
         * LENGTH VALIDATION
         */
        test("Length validation", function() {

            clearForm();

            var tests = [
                {val:input('1234', {'length':'max3', '':'length'}), isValid:false},
                {val:input('1234', {'length':'min3', '':'length'}), isValid:true},
                {val:input('1234', {'length':'min5', '':'length'}), isValid:false},
                {val:input('1234', {'length':'2-35', '':'length'}), isValid:true},
                {val:input('123456', {'length':'2-5', '':'length'}), isValid:false},
                {val:input('1234', {'length':'max4', '':'length'}), isValid:true},
                {val:input('1234', {length : 'min5', '':'number length'}), isValid:false},
                {val:input('12345', {length : 'min5', '':'number length'}), isValid:true},
                {val:input('1234a', {length : 'min5', '':'number length'}), isValid:false},
                {val:input('12345678', {length : 'min5', '':'number length'}), isValid:true},
                {val:input('12345678', {length : '5', '':'number length'}), isValid:false},
                {val:input('12345', {length : '5', '':'number length'}), isValid:true},
                {val:input('123', {length : '5', '':'number length'}), isValid:false}
            ];

            var $select = input('', {length: 'min2', '':'length'}, {}, 'select');
            $select.attr('multiple', 'multiple');
            $select.html('<option selected>A</option><option>B</option>');
            tests.push({
              val: $select,
              isValid: false
            });

            $.each(tests, function(i, obj) {
                runTest(obj, 'length');
            });
        });

        /*
         * VALIDATION WITH IGNORE
         */
        test("Validate with ignore validation", function() {

            clearForm();

            var links = [
                {val:input('1234$', {'length':'max3', '':'length'}), isValid:false},
                {val:input('1234$', {'length':'min3', ignore:'$', '':'length'}), isValid:true},
                {val:input('1234$$$$2$', {ignore:'$', '':'number'}), isValid:true}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'length');
            });
        });

        /*
         * SWEDISH SSN VALIDATION
         */
        test("Swedish SSN validation", function() {

            clearForm();

            var links = [
                {val:'19:59', isValid:false},
                {val:'', isValid:false},
                {val:'198311084936', isValid:true},
                {val:'198311084935', isValid:false},
                {val:'198301128529', isValid:true},
                {val:'198301128528', isValid:false},
                {val:input('', {'use-hyphen' : 'true', '':'swesec'}), isValid:false},
                {val:input('198301128529', {'use-hyphen' : 'true', '':'swesec'}), isValid:false},
                {val:input('198311084936', {'use-hyphen' : 'true', '':'swesec'}), isValid:false},
                {val:input('19830112-8529', {'use-hyphen' : 'true', '':'swesec'}), isValid:true},
                {val:input('19831108-4936', {'use-hyphen' : 'true', '':'swesec'}), isValid:true}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'swesec');
            });
        });

        /*
         * FILE VALIDATION
         */
        test('File validation', function() {

            clearForm();

            equal(100, $.formUtils.convertSizeNameToBytes('100'));
            equal(100, $.formUtils.convertSizeNameToBytes('100b'));
            equal(100, $.formUtils.convertSizeNameToBytes('100B'));
            equal(112640, $.formUtils.convertSizeNameToBytes('110kb'));
            equal(112640, $.formUtils.convertSizeNameToBytes('110KB'));
            equal(10485760, $.formUtils.convertSizeNameToBytes('10M'));
            equal(10485760, $.formUtils.convertSizeNameToBytes('10MB'));
            equal(10485760, $.formUtils.convertSizeNameToBytes('10mb'));
            equal(10485760, $.formUtils.convertSizeNameToBytes('10m'));

            /*
             todo: test this somehow
            var extensionTests = [
                {val:input('file.jpg', {'allowing' : 'jpg', '':'extension'}), isValid:true},
                {val:input('file.JPG', {'allowing' : 'jpg', '':'extension'}), isValid:true},
                {val:input('file.jpgs', {'allowing' : 'jpg', '':'extension'}, {type:'file'}), isValid:false},
                {val:input('file', {'allowing' : 'jpg', '':'extension'}), isValid:false},
                {val:input('file.jpeg', {'allowing' : 'jpg', '':'extension'}), isValid:true},
                {val:input('file.JPEG', {'allowing' : 'jpg, png, gif', '':'extension'}), isValid:true},
                {val:input('file.JPEG', {'allowing' : 'jpg,', '':'extension'}), isValid:true},
                {val:input('file.JPEG', {'allowing' : ' jpg ', '':'extension'}), isValid:true}
            ];

            $.each(extensionTests, function(i, obj) {
                runTest(obj, 'extension');
            });
             */
        });

        test('Sanitation', function() {
            clearForm();

            var sanitationTests = {
                trim : {
                    val : ' apa ',
                    expected : 'apa'
                },
                trimLeft : {
                    val : ' apa ',
                    expected: 'apa '
                },
                trimRight : {
                    val : ' apa ',
                    expected:  ' apa'
                },
                capitalize : {
                    val : 'En groda som Önskar sig öl',
                    expected:  'En Groda Som Önskar Sig Öl'
                },
                'capitalize trim' : {
                    val : ' En groda som Önskar sig öl ',
                    expected:  'En Groda Som Önskar Sig Öl'
                },
                upper : {
                    val : ' apa ',
                    expected:  ' APA '
                },
                lower : {
                    val : ' aPA ',
                    expected:  ' apa '
                },
                insertLeft : {
                    val : ' apa ',
                    expected:  'left... apa ',
                    attr : {
                        'data-sanitize-insert-right' : 'right...',
                        'data-sanitize-insert-left' : 'left...'
                    }
                },
                insertRight : {
                    val : ' apa ',
                    expected:  ' apa right...',
                    attr : {
                        'data-sanitize-insert-right' : 'right...',
                        'data-sanitize-insert-left' : 'left...'
                    }
                },
                insertRightOmitted : {
                    val : ' apa $',
                    expected:  ' apa $',
                    sanitize : 'insertRight',
                    attr : {
                        'data-sanitize-insert-right' : ' $'
                    }
                },
                insertLeftOmitted : {
                    val : '$ apa $',
                    expected:  '$ apa $',
                    sanitize : 'insertRight',
                    attr : {
                        'data-sanitize-insert-left' : '$ '
                    }
                },
                'trim insertRight' : {
                    val : ' apa ',
                    expected:  'apa right...',
                    attr : {
                        'data-sanitize-insert-right' : ' right...'
                    }
                },
                strip: {
                    val: '5$tes6@ti$ng@99$',
                    expected: 'testing99',
                    attr: {
                        'data-sanitize-strip' : '$, @, 5, 6'
                    }
                },
                escape: {
                    val: '<p style="color: pink">hejsan & så\' vidare</p>',
                    expected:  '&lt;p style=&quot;color: pink&quot;&gt;hejsan &amp; så&#8217; vidare&lt;/p&gt;'
                },
                basicNumberFormat1: {
                    val: '-8000.00',
                    expected: '-8,000.0',
                    attr: {
                      'data-sanitize-number-format': '0,0.0'
                    },
                    sanitize: 'numberFormat'
                },
                basicNumberFormat2: {
                    val: '12221.444',
                    expected: '12,221',
                    attr: {
                      'data-sanitize-number-format': '0,0'
                    },
                    sanitize: 'numberFormat'
                }
            };

            $.each(sanitationTests, function(sanitation, data) {
                var $input = input('hejsan', {'':''}, {name:'test'});
                $input.attr('data-sanitize', data.sanitize || sanitation);
                $.each(data.attr || {}, function(attrName, attrVal) {
                    $input.attr(attrName, attrVal);
                });
                $.formUtils.setupSanitation({}, $form, $.formUtils.defaultConfig());

                $input.val(data.val);

                $input.trigger('blur');
                equal($input.val(), data.expected, 'Sanitize with "'+sanitation+'"');
                //Verify that sanitizing twice has no effect
                $input.trigger('focus');
                $input.trigger('blur');
                equal($input.val(), data.expected, 'Sanitize twice with "'+sanitation+'"');
            });

        });

        test('Confirmation', function() {

            clearForm();

            var $inputA = input('hejsan', {'':'confirmation'}, {name:'test'}),
                $inputB = input('hej', undefined, {name:'test_confirmation'}),
                result = $.formUtils.validateInput($inputA, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);

            equal(
                false,
                result.isValid,
                'Could not check that inputs did not confirmation each other'
            );

            $inputB.val('hejsan');
            result = $.formUtils.validateInput($inputA, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(
                result.isValid,
                true,
                'Could not validate confirmation'
            );

            clearForm();

            var $inputC = input('value', {'':'confirmation', 'confirm':'input-D'}, {name:'test'}),
                $inputD = input('hej', undefined, {name:'input-D'});

            result = $.formUtils.validateInput($inputC, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);

            equal(
                result.isValid,
                false,
                'Could not check that inputs did not confirmation each other'
            );

            $inputD.val('value');
            result = $.formUtils.validateInput($inputC, $.formUtils.LANG, $.formUtils.defaultConfig(), $form);
            equal(
                result.isValid,
                true,
                'Could not validate confirmation'
            );
        });

		/*
         * POLAND VALIDATION
         */
        test("Polish PESEL validation", function(){

            clearForm();

            var links = [
                {val:'11310810104', isValid:true},
                {val:'61030604284', isValid:true},
                {val:'04212602595', isValid:true},
                {val:'15251410340', isValid:true},
                {val:'65788768888', isValid:false},
                {val:'12306789761', isValid:false},
                {val:'73896757737', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'plpesel');
            });
        });

        test("Polish NIP validation", function(){

            clearForm();

            var links = [
                {val:'2236473023', isValid:true},
                {val:'6650872044', isValid:true},
                {val:'4622952623', isValid:true},
                {val:'7154300218', isValid:true},
                {val:'3467567875', isValid:false},
                {val:'8676876861', isValid:false},
                {val:'7568876872', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'plnip');
            });
        });

        test("Polish REGON validation", function(){

            clearForm();

            var links = [
                {val:'714379260', isValid:true},
                {val:'951591192', isValid:true},
                {val:'018905922', isValid:true},
                {val:'134533221', isValid:true},
                {val:'21115383251129', isValid:true},
                {val:'05768114548441', isValid:true},
                {val:'71291247784457', isValid:true},
                {val:'87244008641050', isValid:false},
                {val:'8724400864105', isValid:false},
                {val:'010218305', isValid:false},
                {val:'773645358', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'plregon');
            });
        });

        /*
         * UK VALIDATION
         */
        test("UK UTR validation", function(){

            clearForm();

            var links = [
                {val:'9300960004', isValid:true},
                {val:'7795475945', isValid:true},
                {val:'2010335150', isValid:true},
                {val:'3317055678', isValid:true},
                {val:'2444339765', isValid:true},
                {val:'3867839121', isValid:true},
                {val:'38678391210', isValid:false},
                {val:'386783912', isValid:false},
                {val:'1779560363', isValid:false},
                {val:'8648200373', isValid:false},
                {val:'9300648179', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'ukutr');
            });

        });

        test("UK NIN validation", function(){

            clearForm();

            var links = [
                {val:'JX 49 54 09 A', isValid:true},
                {val:'LA 22 26 04 B', isValid:true},
                {val:'LC 34 39 51 C', isValid:true},
                {val:'JX 49 54 09 Z', isValid:false},
                {val:'JX 49 54 09 3', isValid:false},
                {val:'ZZ495409A', isValid:false}
            ];

            $.each(links, function(i, obj) {
                runTest(obj, 'uknin');
            });

        });

        /*
         * COMPLEXITY VALIDATION
         */
        test("Complexity validation", function() {

            clearForm();

            var values = [
                {val:input('abcdefgh', {'':'complexity'}), isValid:true},
                {val:input('ABCDEFGH', {'':'complexity'}), isValid:true},
                {val:input('12345678', {'':'complexity'}), isValid:true},
                {val:input('@|#{}[]', {'':'complexity'}), isValid:true},
                {val:input('abcdefgh', {'require-lc-letter':'2', '':'complexity'}), isValid:true},
                {val:input('abcdefgh', {'require-lc-letter':'2', 'require-length':'9', '':'complexity'}), isValid:false},
                {val:input('abcdefgha', {'require-lc-letter':'2', 'require-length':'9', '':'complexity'}), isValid:true},
                {val:input('12@ABCDEFgh', {'require-lc-letter':'2', '':'complexity'}), isValid:true},
                {val:input('12@ABCDEFGh', {'require-lc-letter':'2', '':'complexity'}), isValid:false},
                {val:input('12@ABCDEFGH', {'require-lc-letter':'2', '':'complexity'}), isValid:false},
                {val:input('12@ABCDEFGH', {'require-uc-letter':'2', '':'complexity'}), isValid:true},
                {val:input('12@abcdefGH', {'require-uc-letter':'2', '':'complexity'}), isValid:true},
                {val:input('12@abcdefgH', {'require-uc-letter':'2', '':'complexity'}), isValid:false},
                {val:input('12@abcdefgh', {'require-uc-letter':'2', '':'complexity'}), isValid:false},
                {val:input('@{}[]', {'require-special-char':'2', '':'complexity'}), isValid:true},
                {val:input('12abcdfgh{}', {'require-special-char':'2', '':'complexity'}), isValid:true},
                {val:input('12abcdefgh{', {'require-special-char':'2', '':'complexity'}), isValid:false},
                {val:input('12abcdefgh', {'require-special-char':'2', '':'complexity'}), isValid:false},
                {val:input('12345678', {'require-numeral':'2', '':'complexity'}), isValid:true},
                {val:input('@abcdfgh78', {'require-numeral':'2', '':'complexity'}), isValid:true},
                {val:input('@abcdefgh1', {'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('@abcdefgh', {'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('abCD{}12', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:true},
                {val:input('abCD{}1', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('abCD{12', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('abC{}12', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('aCD{}12', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('abCD{1', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('abC{1', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('aCD{1', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('aD{1', {'require-lc-letter':'2', 'require-uc-letter':'2', 'require-special-char':'2', 'require-numeral':'2', '':'complexity'}), isValid:false},
                {val:input('aDDFV{}@1356', {'require-lc-letter':'4', 'require-uc-letter':'2', 'require-special-char':'3', 'require-numeral':'2', '':'complexity'}), isValid:false}
            ];

            $.each(values, function(i, obj) {
                runTest(obj, 'complexity');
            });
        });

        test("Color Hex validation", function() {

          clearForm();

          var links = [
            {val: '#0000FF', isValid: true},
            {val: '#00F', isValid: true},
            {val: '123', isValid: false},
            {val: '112233', isValid: false},
            {val: '#4567', isValid: false},
            {val: input('transparent', {'allow-transparent': 'true'}), isValid: true},
            {val: 'transparent', isValid: false}
          ];

          $.each(links, function(i, obj) {
            runTest(obj, 'hex');
          });
        });

        test("Color Rgb validation", function() {

          clearForm();

          var links = [
            {val: 'rgb(255,255,255)', isValid: true},
            {val: 'rgb( 255 , 255 , 255 )', isValid: true},
            {val: 'rgb( 255, 255, 255 )', isValid: true},
            {val: 'rgb(255,255,255)', isValid: true},


            {val: 'rgb(-10,255,255)', isValid: false},
            {val: '255255255', isValid: false},
            {val: 'rgb(255,255,256)', isValid: false},


            {val: input('transparent', {'allow-transparent': 'true'}), isValid: true},
            {val: 'transparent', isValid: false}
          ];

          $.each(links, function(i, obj) {
            runTest(obj, 'rgb');
          });
        });

      test("Color Rgba validation", function() {

        clearForm();

        var links = [
          {val: 'rgba(255,255,255,1)', isValid: true},
          {val: 'rgba( 255 , 255 , 255 , 1 )', isValid: true},
          {val: 'rgba( 255 , 255 , 255 , 1 )', isValid: true},
          {val: 'rgba(255,255,255,1)', isValid: true},
          {val: 'rgba(255,255,255,0)', isValid: true},
          {val: 'rgba(255,255,255,1)', isValid: true},
          {val: 'rgba(255,255,255,0.5)', isValid: true},
          {val: 'rgba(255,255,255,.5)', isValid: true},
          {val: 'rgba(255,255,255,.524141)', isValid: true},
          {val: 'rgba(255,255,255,2)', isValid: false},
          {val: 'rgba(255,255,255,-1)', isValid: false},
          {val: 'rgba(255,255,255,1.000000000001)', isValid: false},
          {val: 'rgba(255,255,255,-0.5)', isValid: false},
          {val: 'rgba(255,255,255,2.3)', isValid: false},
          {val: 'rgba(-10,255,255,1)', isValid: false},
          {val: '2552552551', isValid: false},
          {val: 'rgba(255,255,256),1', isValid: false},
          {val: '0000FF', isValid: false},
          {val: input('transparent', {'allow-transparent': 'true'}), isValid: true},
          {val: 'transparent', isValid: false}
        ];

        $.each(links, function(i, obj) {
          runTest(obj, 'rgba');
        });
      });

      test("Color Hsl validation", function() {

        clearForm();

        var links = [
          {val: 'hsl(120,50%,50%)', isValid: true},
          {val: 'hsl( 120 , 50% , 50% )', isValid: true},
          {val: 'hsl( 120, 50%, 50% )', isValid: true},
          {val: 'hsl(-120,50%,50%)', isValid: true},
          {val: 'hsl(480,50%,50%)', isValid: true},

          {val: 'hsl(10,-50%,50%)', isValid: false},
          {val: 'hsl(10,50%,-50%)', isValid: false},
          {val: '120,50%,50%', isValid: false},
          {val: 'hsl(120,100%,101%)', isValid: false},
          {val: 'hsl(50%, 50%, 100%)', isValid: false},
          {val: 'hsl(120, 50, 100%)', isValid: false},
          {val: 'hsl(120, 50%, 100)', isValid: false},

          {val: input('transparent', {'allow-transparent': 'true'}), isValid: true},
          {val: 'transparent', isValid: false}
        ];

        $.each(links, function(i, obj) {
          runTest(obj, 'hsl');
        });
      });

      test("Color Hsla validation", function() {

        clearForm();

        var links = [
          {val: 'hsla(120,50%,50%,1)', isValid: true},
          {val: 'hsla( 120 , 50% , 50%, 1 )', isValid: true},
          {val: 'hsla( 120, 50%, 50% , 1 )', isValid: true},
          {val: 'hsla(-120,50%,50%,1)', isValid: true},
          {val: 'hsla(480,50%,50%,1)', isValid: true},
          {val: 'hsla(120,50%,100%,0)', isValid: true},
          {val: 'hsla(120,50%,100%,1)', isValid: true},
          {val: 'hsla(120,50%,100%,0.5)', isValid: true},
          {val: 'hsla(120,50%,100%,.5)', isValid: true},
          {val: 'hsla(120,50%,100%,.524141)', isValid: true},

          {val: 'hsla(120,50%,100%,50%)', isValid: false},
          {val: 'hsla(120,50%,100%,2)', isValid: false},
          {val: 'hsla(120,50%,100%,-1)', isValid: false},
          {val: 'hsla(120,50%,100%,1.000000000001)', isValid: false},
          {val: 'hsla(120,50%,100%,-0.5)', isValid: false},
          {val: 'hsla(120,50%,100%,2.3)', isValid: false},
          {val: 'hsla(10,-50%,50%,1)', isValid: false},
          {val: 'hsla(10,50%,-50%,1)', isValid: false},
          {val: '120,50%,50%,1', isValid: false},
          {val: 'hsla(120,100%,101%,1)', isValid: false},
          {val: 'hsla(50%, 50%, 100%,1)', isValid: false},
          {val: 'hsla(120, 50, 100%,1)', isValid: false},
          {val: 'hsla(120, 50%, 100,1)', isValid: false},

          {val: input('transparent', {'allow-transparent': 'true'}), isValid: true},
          {val: 'transparent', isValid: false}
        ];

        $.each(links, function(i, obj) {
          runTest(obj, 'hsla');
        });
      });

        // TODO: Write more tests...
    }

    $.validate({
        modules : 'security, location, sweden, file, date, sanitize, uk, poland, color',
        onModulesLoaded: function( $form ) {
            if( window.console && window.console.log )
                console.log('About to run all tests');

            runAllTests();
        }
    });

})(jQuery);
</script>

</body>
</html>
